// 这个文件就是二次封装axios， 因为你要给axios加一些 请求基地址，或者配置拦截器，
import axios from 'axios'
import store from '@/store'
import router from '@/router'
// import { message } from 'element-ui'

// 怎么封装？去看官网，或者百度搜索  “vue axios 二次封装”
const request = axios.create({
  // baseURL 是所有请求的前缀， 基地址
  baseURL: '/api',
  // timeout请求超时时间，超过了6s就会报错
  timeout: 6000
})

// 请求拦截器 --- 请求之前执行的函数， 2个参数， 请求发成功的回调函数，请求发失败的回调函数
// 请求拦截器有几个参数？
// 有两个参数， 分别是两个回调函数(开始的时候不执行，回过头来，在特定的时机在执行)
// 第一个回调函数，是请求发送成功以后执行的函数
// 第二个回调函数，是请求发送失败以后执行的函数
request.interceptors.request.use((config) => {
//  console.log('1请求发成功的回调函数')
  // 后面会在这里 给所有的请求 加一个请求头 里面携带token
  if (store.state.user.token) {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  return config
}, (error) => {
  // console.log('2请求发送失败的回调函数')
  return Promise.reject(error)
})

// 响应拦截器 --- 服务器给相应数据到业务之前
// 响应拦截器的参数？
// 有2个参数，分别是2个回调函数
// 第一个回调函数。 是服务器响应成功以后执行的回调函数
// 第二个回调函数，是服务器响应式失败以后（401 500 403 404 。。。） 以后执行的回调函数
request.interceptors.response.use((response) => {
  // console.log('3服务器响应成功')
  if (response.data instanceof Blob) return response.data // 返回了Blob对象
  return response
}, (error) => {
  console.log('4服务器响应失败')
  // 涉及到Promise的底层， promise3个状态， pending 等待 resolve 成功 reject 失败
  // 这里如果 reject，那么在业务代码那边，就会执行 .catch的代码
  // 这里如果 resolve，那么在业务代码那边，就会执行 .then的代码
  // 因为这里已经是报错了，所以，我们这里必须写reject，告诉业务代码，我们这里报错了，请你用catch接受一下
  // 但是自己心里要清楚，如果这里写resolve，那么业务那边走的绝对是then里面的代码
  // 若token失效 报错401 ,则需要退出登录,删除本地存储里面的token
  if (error?.response?.status === 401) {
    // 调用 vuex中的action 方法 退出登录,删除本地存储里面的token
    store.dispatch('user/removeToken')
    // 主动跳回登录页面
    router.push('/login')
  }
  return Promise.reject(error)
})

export default request
